package com.tarena.lbs.business.servcie.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.attach.pojo.param.PicUpdateParam;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.business.constant.BusinessTypes;
import com.tarena.lbs.business.dao.repository.BusinessRepository;
import com.tarena.lbs.business.pojo.param.BusinessParam;
import com.tarena.lbs.business.pojo.po.BusinessPO;
import com.tarena.lbs.business.pojo.po.StorePO;
import com.tarena.lbs.business.pojo.query.BusinessQuery;
import com.tarena.lbs.business.pojo.vo.BusinessStoreVO;
import com.tarena.lbs.business.pojo.vo.BusinessVO;
import com.tarena.lbs.business.pojo.vo.StoreVO;
import com.tarena.lbs.business.servcie.BusinessService;
import com.tarena.lbs.common.encoder.JwtEncoder;
import com.tarena.lbs.common.enums.Roles;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.commons.security.ResourceServerTokenRelayAutoConfiguration;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BusinessServiceImpl implements BusinessService {

    @DubboReference
    private BusinessRepository businessRepository;

    @DubboReference
    private AttachApi attachApi;

    private final JwtEncoder jwtEncoder;
    private final ResourceServerTokenRelayAutoConfiguration resourceServerTokenRelayAutoConfiguration;

    public BusinessServiceImpl(JwtEncoder jwtEncoder, ResourceServerTokenRelayAutoConfiguration resourceServerTokenRelayAutoConfiguration) {
        this.jwtEncoder = jwtEncoder;
        this.resourceServerTokenRelayAutoConfiguration = resourceServerTokenRelayAutoConfiguration;
    }

    @Override
    public PageResult<BusinessVO> pageList(BusinessQuery query) {
        // 创建一个新的分页结果对象，用于存储最终的分页查询结果
        PageResult<BusinessVO> voPage = new PageResult<>();
        
        // 调用 businessRepository 的 pagesList 方法进行分页查询，获取包含商家持久化对象的分页信息
        PageInfo<BusinessPO> pageInfo = businessRepository.pagesList(query);
        
        // 将分页信息中的页码设置到分页结果对象中
        voPage.setPageNo(pageInfo.getPageNum());
        // 将分页信息中的每页数量设置到分页结果对象中
        voPage.setPageSize(pageInfo.getPageSize());
        // 将分页信息中的总记录数设置到分页结果对象中
        voPage.setTotal(pageInfo.getTotal());
        
        // 声明一个存储商家视图对象的列表
        List<BusinessVO> vos = null;
        // 从分页信息中获取商家持久化对象列表
        List<BusinessPO> pos = pageInfo.getList();
        // 判断持久化对象列表是否不为空
        if (CollectionUtils.isNotEmpty(pos)){
            vos = pos.stream().map(po -> {
                BusinessVO vo = new BusinessVO();
                BeanUtils.copyProperties(po, vo);
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(BusinessParam param) throws BusinessException {
        //1.检查当前登录用户的角色是否符合我当前业务的角色要求
        // ADMIN 平台管理员 才能创建商家  SHOP 商家账号 能创建店铺
        checkRole(Roles.ADMIN);

        //2.验证检查幂等 是否存在相同名称的商家数据
        // 通过查询所有商家来检查名称是否重复
        List<BusinessPO> allBusinesses = businessRepository.getBusinesses();
        boolean nameExists = allBusinesses.stream()
                .anyMatch(business -> business.getBusinessName().equals(param.getBusinessName()));
        Asserts.isTrue(nameExists, new BusinessException("-1","商家名称已存在"));
        //3.幂等验证正常 可以新增 封装 数据对象PO 执行save新增
        Integer id = saveBusiness(param);
//        //4.新增之后的商家 有了id 定义 type 100营业执照 200logo调用图片绑定
//        bindPictures(id, param);
    }

    @Override
    public BusinessStoreVO getBusinessWithStores(Integer businessId) throws BusinessException {
        // 1. 查询商家基本信息
        BusinessPO businessPO = businessRepository.getBusinessById(businessId);
        if (businessPO == null) {
            throw new BusinessException("-1", "商家不存在");
        }

        // 2. 查询该商家旗下的店铺列表（假设repository中有相应方法）
         List<StorePO> storePOs = businessRepository.getStoresByBusinessId(businessId);

        // 3. 封装BusinessStoreVO对象
        BusinessStoreVO businessStoreVO = new BusinessStoreVO();
        BeanUtils.copyProperties(businessPO, businessStoreVO);

        // 4. 设置店铺列表（如果需要）
         businessStoreVO.setStoreVOList(storePOs.stream().map(po -> {
             StoreVO storeVO = new StoreVO();
             BeanUtils.copyProperties(po, storeVO);
             return storeVO;
         }).collect(Collectors.toList()));

        return businessStoreVO;
    }

//    private void bindPictures(Integer businessId, BusinessParam param) throws BusinessException {
//        //商家新增 图片 要绑定两张 一张营业执照 一张logo
//        //准备一下 接口的入参
//        List<PicUpdateParam> picParams=new ArrayList<>();
//        //准备一个PicUpdateParam 存储营业执照 的绑定参数
//        PicUpdateParam licenseParam=new PicUpdateParam();
//        //bizType 100 表示商家营业执照
//        licenseParam.setBusinessType(BusinessTypes.BIZ_LICENSE);
//        //bizId 商家id
//        licenseParam.setBusinessId(businessId);
//        //可以在对象里绑定图片id或者图片fileUuid 当前业务无法获取图片id只能获取fileUuid
//        //http://localhost:9081/static/19fh93gr931h10rf3h29r.png 最后的值是fileUuid的拼接 19fh93gr931h10rf3h29r.png
//        String licenseUrl = param.getBusinessLicense();
//        licenseParam.setFileUuid(getFileUuidFromUrl(licenseUrl));
//        //准备第二个绑定图片的入参元素 绑定logo
//        PicUpdateParam logoParam=new PicUpdateParam();
//        logoParam.setBusinessType(BusinessTypes.BIZ_LOGO);
//        logoParam.setBusinessId(businessId);
//        String logoUrl = param.getBusinessLogo();
//        logoParam.setFileUuid(getFileUuidFromUrl(logoUrl));
//        //将营业执照图片数据 和log图片数据放到list中
//        picParams.add(licenseParam);
//        picParams.add(logoParam);
//        boolean result = attachApi.batchUpdateBusiness(picParams);
//        Asserts.isTrue(!result,new BusinessException("-2","业务绑定失败"));
//    }

//    /**
//     * 从图片URL中提取fileUuid
//     * @param imageUrl 图片URL，格式如：http://localhost:9081/static/19fh93gr931h10rf3h29r.png
//     * @return fileUuid，不包含扩展名的部分
//     */
//    private String getFileUuidFromUrl(String imageUrl) {
//        if (imageUrl == null || imageUrl.trim().isEmpty()) {
//            return null;
//        }
//        // 提取路径部分
//        String path = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
//
//        // 移除扩展名，只保留fileUuid
//        int dotIndex = path.lastIndexOf(".");
//        if (dotIndex > 0) {
//            return path.substring(0, dotIndex);
//        }
//
//        return path; // 如果没有扩展名，返回整个路径
//    }

    private Integer saveBusiness(BusinessParam param) {
        log.info("保存商家数据：{}", param);
        BusinessPO businessPO = new BusinessPO();
        BeanUtils.copyProperties(param, businessPO);
        businessPO.setEntryTime(new Date());
        businessRepository.save(businessPO);
        return businessPO.getId();
    }

    private void checkRole(Roles requiredRole) throws BusinessException {
        // 1. 从ThreadLocal获取当前登录用户信息（确保是当前登录用户）
        UserPrinciple currentUser = AuthenticationContextUtils.get();

        // 2. 校验是否登录：未登录则阻断
        if (currentUser == null) {
            throw new BusinessException("-1","请先登录，仅登录用户可操作");
        }

        // 3. 获取当前用户的角色类型（与Roles枚举的type匹配）
        Integer userRoleType = currentUser.getRole().getType(); // 假设UserPrinciple有此方法
        if (userRoleType == null) {
            throw new BusinessException("-2","用户角色信息缺失，请联系管理员");
        }

        // 4. 严格校验是否为指定角色（此处即ADMIN，type=0）
        if (!requiredRole.getType().equals(userRoleType)) {
            // 解析当前用户的实际角色，返回清晰的异常信息
           throw new BusinessException("-3","当前用户角色不符合要求，请检查");
        }
    }
}